// wiring_interrupt.c
#include "pin_map.h"
#include "wiring_interrupt.h"
#include "stm32f10x_exti.h"
#include "misc.h"

#include <stdint.h>

// 存储每个 EXTI 线的回调函数（Line 0~15）
static voidFuncPtr exti_callbacks[16] = {NULL};

// 触发模式映射
static EXTITrigger_TypeDef get_exti_trigger(InterruptMode mode) {
    switch (mode) {
        case RISING:  return EXTI_Trigger_Rising;
        case FALLING: return EXTI_Trigger_Falling;
        case CHANGE:  return EXTI_Trigger_Rising_Falling;
        default:      return EXTI_Trigger_Rising_Falling;
    }
}

// 获取引脚编号
static uint8_t get_pin_num(GPIO_PinName pin) {
    return pin & 0x0F;
}

// 获取端口源
static uint8_t get_port_source(GPIO_PinName pin) {
    if (pin <= GPIO_PIN_PA15) return GPIO_PortSourceGPIOA;
    if (pin >= GPIO_PIN_PB0 && pin <= GPIO_PIN_PB15) return GPIO_PortSourceGPIOB;
    if (pin >= GPIO_PIN_PC0 && pin <= GPIO_PIN_PC15) return GPIO_PortSourceGPIOC;
    if (pin >= GPIO_PIN_PD0 && pin <= GPIO_PIN_PD15) return GPIO_PortSourceGPIOD;
    return GPIO_PortSourceGPIOA;
}

// 配置 NVIC 优先级（可配置）
static void enable_exti_irq(uint8_t irq_channel) {
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = irq_channel;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

// attachInterrupt 实现
void attachInterrupt(GPIO_PinName pin, voidFuncPtr handler, InterruptMode mode)
{
    if (pin == GPIO_PIN_NONE || pin >= PIN_COUNT) return;

    uint8_t pin_num = get_pin_num(pin);
    uint32_t exti_line = (1 << pin_num);

    // 1. 配置 AFIO：将引脚映射到 EXTI
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
    GPIO_EXTILineConfig(get_port_source(pin), pin_num);

    // 2. 设置回调
    exti_callbacks[pin_num] = handler;

    // 3. 配置 EXTI
    EXTI_InitTypeDef EXTI_InitStructure;
    EXTI_InitStructure.EXTI_Line = exti_line;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = get_exti_trigger(mode);
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);

    // 4. 使能 NVIC
    if (pin_num == 0) {
        enable_exti_irq(EXTI0_IRQn);
    } else if (pin_num == 1) {
        enable_exti_irq(EXTI1_IRQn);
    } else if (pin_num == 2) {
        enable_exti_irq(EXTI2_IRQn);
    } else if (pin_num == 3) {
        enable_exti_irq(EXTI3_IRQn);
    } else if (pin_num == 4) {
        enable_exti_irq(EXTI4_IRQn);
    } else if (pin_num >= 5 && pin_num <= 9) {
        enable_exti_irq(EXTI9_5_IRQn);
    } else if (pin_num >= 10 && pin_num <= 15) {
        enable_exti_irq(EXTI15_10_IRQn);
    }
}

// 全局中断服务函数（自动调用注册的回调）

void EXTI0_IRQHandler(void) {
    if (EXTI_GetITStatus(EXTI_Line0)) {
        if (exti_callbacks[0]) exti_callbacks[0]();
        EXTI_ClearITPendingBit(EXTI_Line0);
    }
}

void EXTI1_IRQHandler(void) {
    if (EXTI_GetITStatus(EXTI_Line1)) {
        if (exti_callbacks[1]) exti_callbacks[1]();
        EXTI_ClearITPendingBit(EXTI_Line1);
    }
}

void EXTI2_IRQHandler(void) {
    if (EXTI_GetITStatus(EXTI_Line2)) {
        if (exti_callbacks[2]) exti_callbacks[2]();
        EXTI_ClearITPendingBit(EXTI_Line2);
    }
}

void EXTI3_IRQHandler(void) {
    if (EXTI_GetITStatus(EXTI_Line3)) {
        if (exti_callbacks[3]) exti_callbacks[3]();
        EXTI_ClearITPendingBit(EXTI_Line3);
    }
}

void EXTI4_IRQHandler(void) {
    if (EXTI_GetITStatus(EXTI_Line4)) {
        if (exti_callbacks[4]) exti_callbacks[4]();
        EXTI_ClearITPendingBit(EXTI_Line4);
    }
}

void EXTI9_5_IRQHandler(void) {
    for (int i = 5; i <= 9; i++) {
        if (EXTI_GetITStatus(1 << i)) {
            if (exti_callbacks[i]) exti_callbacks[i]();
            EXTI_ClearITPendingBit(1 << i);
        }
    }
}

void EXTI15_10_IRQHandler(void) {
    for (int i = 10; i <= 15; i++) {
        if (EXTI_GetITStatus(1 << i)) {
            if (exti_callbacks[i]) exti_callbacks[i]();
            EXTI_ClearITPendingBit(1 << i);
        }
    }
}
